package com.g4.shoppingback.aspect;

import com.g4.shoppingback.annotation.WriteLog;
import com.g4.shoppingback.pojo.DdLogs;
import com.g4.shoppingback.service.DdLogsService;
import com.g4.shoppingback.service.IRoleService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;

@Component
@Aspect //切面
public class LogAspect {

    @Autowired
    private IRoleService iRoleService;
    @Autowired
    private DdLogsService ddLogsService;

    //切入点表达式
    @Pointcut("@annotation(com.g4.shoppingback.annotation.WriteLog)")
    public void pointCut(){}

    //通知
    @Around("@annotation(action)")
    public Object around(ProceedingJoinPoint joinPoint, WriteLog action) throws Throwable {
        long startTime = System.currentTimeMillis();
        long useTime =0;
        Integer flag =1; //默认状态正常
        String msg = "";
        try {
            Object proceed = joinPoint.proceed();
            long endTime = System.currentTimeMillis();
            useTime = endTime - startTime; //正常耗时
            return proceed;
        }catch (Exception e){
            long endTime = System.currentTimeMillis();
            useTime = endTime - startTime; //错误耗时
            flag = 0; //状态改为不正常
            msg = e.getMessage(); //错误信息
            throw e;
        }finally {
            saveLog(joinPoint,action,useTime,flag,msg);
        }
    }

    private void saveLog(ProceedingJoinPoint joinPoint, WriteLog action,
                         long useTime, Integer flag, String msg) throws IOException {
        //1.获取用户名
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = (String)authentication.getPrincipal();
        //2.获取角色
        String role = iRoleService.selectRoleByName(username);
        //3.获取操作行为
        String operation = action.value();
        //4.获取使用的方法
        String method = joinPoint.getSignature().getName();
        //5.方法参数
        String paramsArray = new ObjectMapper().writeValueAsString(joinPoint.getArgs());
        String params = paramsArray.substring(1, paramsArray.length()-1);
        //6.操作耗时
        Long time = useTime;
        //7.用户ip
        HttpServletRequest request =
                ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String ip = request.getRemoteAddr();
        //8.操作当前时间
        //SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //String createTime = simpleDateFormat.format(new Date());
        Date createTime = new Date();
        //9.操作是否成功
        Integer status = flag;
        //10.发生的错误,没有则为null
        String error =  msg==""?"无":msg ;  //发生的错误
        DdLogs ddLogs = new DdLogs().setUsername(username).setRole(role)
                .setOperation(operation).setMethod(method).setParams(params)
                .setTime(time).setIp(ip).setCreatedTime(createTime).setStatus(flag).setError(error);
        ddLogsService.addLog(ddLogs);
    }


}
